<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <style>
    table {
       border-collapse: collapse;
     }
     th, td {
       border: 1px solid black;
       padding: 4px;
     }
     th {
       cursor: pointer;
     }
     th:hover {
       background: yellow;
     }
  </style>
</head>

<body>

  <table id="grid">
    <thead>
      <tr>
        <th data-type="number">나이</th>
        <th data-type="string">이름</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>5</td>
        <td>일리야</td>
      </tr>
      <tr>
        <td>2</td>
        <td>보라</td>
      </tr>
      <tr>
        <td>12</td>
        <td>호진</td>
      </tr>
      <tr>
        <td>9</td>
        <td>지민</td>
      </tr>
      <tr>
        <td>1</td>
        <td>재인</td>
      </tr>
    </tbody>
  </table>

  <script>

    grid.onclick = function(e) {
      if (e.target.tagName != 'TH') return;

      let th = e.target;
      // 클릭한 요소가 TH라면 정렬을 진행합니다.
      // cellIndex는 몇 번째 열인지를 나타내는 인덱스 값입니다.
      //   첫 번째 열이라면 0,
      //   두 번째 열이라면 1이 됩니다.
      sortGrid(th.cellIndex, th.dataset.type);
    };

    function sortGrid(colNum, type) {
      let tbody = grid.querySelector('tbody');

      let rowsArray = Array.from(tbody.rows);

      // 변수 compare에 할당할 함수 compare(a, b)는 두 행을 비교하고 필요에 따라 정렬을 진행합니다.
      let compare;

      switch (type) {
        case 'number':
          compare = function(rowA, rowB) {
            return rowA.cells[colNum].innerHTML - rowB.cells[colNum].innerHTML;
          };
          break;
        case 'string':
          compare = function(rowA, rowB) {
            return rowA.cells[colNum].innerHTML > rowB.cells[colNum].innerHTML ? 1 : -1;
          };
          break;
      }

      // 해당 열을 정렬합니다.
      rowsArray.sort(compare);

      tbody.append(...rowsArray);
    }
  </script>

</body>
</html>
